<template>
  <div class="page">
    <form class="in-coder-panel">
      <textarea
        ref="editorRef"
        class="textarea"
        v-model="code"
        name="code"
        id="code"
      ></textarea>
      <div class="code-tools" :class="{ fixed: fullScreenBol }">
        <el-select
          v-model="mode"
          @change="changeMode"
          v-show="props.showSelection"
        >
          <el-option
            v-for="(item, key) in modes"
            :key="key"
            :label="key"
            :value="key"
          >
          </el-option>
        </el-select>
        <div @click="fullScreen">
          <svg
            v-if="!fullScreenBol"
            t="1650873221736"
            class="icon"
            viewBox="0 0 1024 1024"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            p-id="2021"
            width="200"
            height="200"
          >
            <path
              d="M358.4 768H426.666667v85.333333H213.333333v-213.333333h85.333334v68.266667l128-128 59.733333 59.733333-128 128z m345.6 0l-128-128 59.733333-59.733333 132.266667 132.266666V640h85.333333v213.333333h-213.333333v-85.333333h64zM358.4 298.666667l128 128-59.733333 59.733333-128-128V426.666667H213.333333V213.333333h213.333334v85.333334H358.4z m345.6 0H640V213.333333h213.333333v213.333334h-85.333333V354.133333l-132.266667 132.266667-59.733333-59.733333 128-128z"
              fill="#ffffff"
              p-id="2022"
            ></path>
          </svg>
          <svg
            v-else
            t="1650873294813"
            class="icon"
            viewBox="0 0 1024 1024"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            p-id="2190"
            width="200"
            height="200"
          >
            <path
              d="M298.666667 631.466667H226.133333v-81.066667h217.6v204.8h-85.333333v-68.266667l-128 128L170.666667 759.466667l128-128z m422.4 0l128 128-59.733334 59.733333-128-128v68.266667h-85.333333V554.666667h217.6v81.066666h-72.533333zM298.666667 341.333333L187.733333 230.4 243.2 170.666667l115.2 115.2V217.6h85.333333v204.8H226.133333V341.333333H298.666667z m430.933333 0h64v81.066667h-217.6V217.6h85.333333v72.533333L780.8 170.666667l59.733333 59.733333L729.6 341.333333z"
              fill="#ffffff"
              p-id="2191"
            ></path>
          </svg>
        </div>
      </div>
    </form>
  </div>
</template>

<script lang="ts" setup>
import Codemirror from 'codemirror'
// 核心样式
import 'codemirror/lib/codemirror.css'
// 全屏显示
import 'codemirror/addon/display/fullscreen.css'
import 'codemirror/addon/display/fullscreen.js'

// language
import 'codemirror/mode/shell/shell.js'
import 'codemirror/mode/sql/sql.js'
import 'codemirror/mode/python/python.js'
import 'codemirror/mode/javascript/javascript.js'

// 引入主题后还需要在 options 中指定主题才会生效
import 'codemirror/theme/dracula.css'
import {
  onMounted,
  ref,
  defineProps,
  defineEmits,
  computed,
  nextTick
} from 'vue'

const props = defineProps({
  value: String,
  language: String,
  showSelection: Boolean
})

const emits = defineEmits(['update:value'])
// 语言选择
const mode = ref(props.language || 'Shell')
const modes = {
  Shell: 'x-sh',
  SQL: 'x-sql',
  Python: 'x-python',
  javascript: 'javascript'
}
const changeMode = (val) => {
  mode.value = val
  editor.setOption('mode', `text/${modes[mode.value]}`)
}

// 实例编辑器
const code = computed({
  get: () => props.value,
  set: (val) => emits('update:value', val)
})
const fullScreenBol = ref(false)
const editorRef = ref()
let editor
onMounted(() => {
  nextTick(() => {
    editor = Codemirror.fromTextArea(editorRef.value, {
      mode: `text/${modes[mode.value]}`,
      // 主题，对应主题库 JS 需要提前引入
      theme: 'dracula',
      // 缩进格式
      tabSize: 2,
      // 显示行号
      lineNumbers: true,
      extraKeys: {
        F11: fullScreen,
        Esc: function (cm) {
          if (cm.getOption('fullScreen')) {
            fullScreenBol.value = false
            cm.setOption('fullScreen', false)
          }
        }
      }
    })
    editor.on('change', (cm: any) => {
      code.value = cm.getValue()
    })
  })
})

const fullScreen = () => {
  fullScreenBol.value = !editor.getOption('fullScreen')
  editor.setOption('fullScreen', fullScreenBol.value)
}
</script>
<style>
.page {
  width: 100vw;
  height: 100vh;
}
.CodeMirror {
  border: 1px solid black;
}
.in-coder-panel {
  position: relative;
  margin: 20px;
}
.in-coder-panel .cm-string {
  font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono,
    DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;
}
.code-tools {
  position: absolute;
  right: 0px;
  top: 10px;
  display: flex;
  z-index: 9;
}
.code-tools.fixed {
  position: fixed;
}
.code-tools > div {
  margin-right: 10px;
}
.code-tools .icon {
  width: 32px;
  height: 32px;
}
</style>
